package com.yu.blog.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;


/**
 * AES加密解密工具
 */
@Slf4j
@Component
public class AESUtils {

    /**
     * 默认密钥
     * 十六位十六进制数作为秘钥
     */
    public static String SECRET_KEY;

    @Value("${AESutils.SECRET_KEY}")
    public void setSecretKey(String secretKey) {
        SECRET_KEY = secretKey;
    }

    /**
     * 默认秘钥偏移量
     * 十六位十六进制数作为秘钥偏移量
     */
    public static String SECRET_IV;

    @Value("${AESutils.SECRET_IV}")
    public void setSecretIv(String secretIv) {
        SECRET_IV = secretIv;
    }
    /* -------------------------------------------- AES-128-CBC加密解密 ------------------------------------------ */


    /**
     * AES-128-CBC加密
     * 填充方式(Padding)：PKCS7Padding
     * 目前Java及Vue均可加密解密
     */
    public static String encryptPkcs7(String sSrc) {
        if (SECRET_KEY.length() != 16) {
            log.error("密钥长度必须为16位");
            return null;
        }
        if (SECRET_IV.length() != 16) {
            log.error("秘钥偏移量长度必须为16位");
            return null;
        }
        try {
            byte[] sourceBytes = sSrc.getBytes(StandardCharsets.UTF_8);
            byte[] keyBytes = SECRET_KEY.getBytes(StandardCharsets.UTF_8);
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
            IvParameterSpec iv = new IvParameterSpec(SECRET_IV.getBytes(StandardCharsets.UTF_8));
            cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, "AES"), iv);
            byte[] decrypted = cipher.doFinal(sourceBytes);
            return Base64.encodeBase64String(decrypted);
        } catch (Exception ex) {
            log.error("加密出错：", ex);
            ex.printStackTrace();
            return null;
        }
    }

    /**
     * AES-128-CBC解密
     * 填充方式(Padding)：PKCS7Padding
     * 目前Java及Vue均可加密解密
     */
    public static String decryptPkcs7(String sSrc) {
        if (SECRET_KEY.length() != 16) {
            log.error("密钥长度必须为16位");
            return null;
        }
        if (SECRET_IV.length() != 16) {
            log.error("秘钥偏移量长度必须为16位");
            return null;
        }
        try {
            byte[] sourceBytes = Base64.decodeBase64(sSrc);
            byte[] keyBytes = SECRET_KEY.getBytes(StandardCharsets.UTF_8);
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
            IvParameterSpec iv = new IvParameterSpec(SECRET_IV.getBytes(StandardCharsets.UTF_8));
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, "AES"), iv);
            byte[] decoded = cipher.doFinal(sourceBytes);
            return new String(decoded, StandardCharsets.UTF_8);
        } catch (Exception ex) {
            log.error("解密出错：", ex);
            ex.printStackTrace();
            return null;
        }
    }

}

